package com.gitee.feizns.bean;

import com.gitee.feizns.StreamUtils;
import com.gitee.feizns.reflect.ConstructorUtils;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * java bean.
 * @author feizns
 * @since 2019/6/9 0009
 */
public abstract class BeanUtils {

    /**
     * 复制属性
     * @param target
     * @param source
     * @param <T>
     * @return
     */
    public static final <T> T copyProperties(T target, Object... source) {
        return copyProperties(target, StreamUtils::noChangeFun, source);
    }

    /**
     * 复制属性
     * @param target
     * @param source
     * @param <T>
     * @return
     */
    public static final <T> T copyProperties(T target, Function<String, String> keyMap, Object... source) {
        Map<String, Property<Object>> map = PropertyUtils.writableProps(target)
                .collect(Collectors.toMap(Property::name, item -> item, StreamUtils::leaveSecond, LinkedHashMap::new));
        for (Object o : source) {
            PropertyUtils.readableProps(o).forEach(prop -> {
                String newKey = keyMap.apply(prop.name());
                Property<Object> property = map.get(newKey);
                if ( property != null )
                    property.set(prop.val());
            });
        }
        return target;
    }

    /**
     * 新创建一个对象复制属性
     * @param targetType
     * @param source
     * @param <T>
     * @return
     */
    public static final <T> T copyProperties(Class<T> targetType, Object... source) {
        return copyProperties(ConstructorUtils.newInstance(targetType), source);
    }

    /**
     * 新创建一个对象复制属性
     * @param targetType
     * @param source
     * @param <T>
     * @return
     */
    public static final <T> T copyProperties(Class<T> targetType, Function<String, String> keyMap, Object... source) {
        return copyProperties(ConstructorUtils.newInstance(targetType), keyMap, source);
    }

}
